// "Copyright [2021] <Copyright Shengkai Lin>"

cplusplus{{
    #include <vector>
    #include <utility>
    #include <unordered_map>
    #include "../basic.h"
}}

namespace ai_sim;

class Task {
    @existingClass;
};
class IntPairVector {
    @existingClass;    
};
class RouteVec {
    @existingClass;
};

class Flow {
    @existingClass;
};
class FlowVector {
    @existingClass;
};

enum CLUSTER_MSGS {
    UNKONWN_MSG = 0;

    // Used when the cpu tell the gpu to send a data msg.
    FLOW_ALLOC_MSG =1;
    
    DATA_MSG = 2;
    // TORUS_DATA_MSG = 2;
    
    // Used when gpu received a DataMsg and send this to cpu
    RECEIVED_MSG = 3;
    
    // Used when cpu find out that it have done the allreduce 
    // of a batch, and will send this to the master cpu.
    SYNC_MSG = 4;
    
    // Used when the task generator allocate a new task to the
    // central controller and then to the machine
    // Carries the info of a task.
    TASK_ALLOC_MSG = 5;

    // Used when the cpu has finished a task and inform the
    // controller
    FINISHED_MSG = 6;

    // Used when the network controller allocate the route of the
    // switchs.
    // Carries the new route of map class
    ROUTE_ALLOC_MSG = 7;

    // Used in the scheduleAt() func
    SELF_MSG = 8;

    // Used when the switches have not finshed its switch event yet
    // And send a wait msg to the src app.
    WAIT_MSG = 9;

    // Used in butterfly, when a new flow need to change the route for
    // itself, then send the msg from Cpu to controller
    CHANGE_ROUTE_MSG = 10;

    // The msg kind is used at the detect mode of the nic, used to detect
    // if the link is ready.
    DETECT_MSG = 11;

    // DCQCN
    ACK_MSG = 12;

    NACK_MSG = 13;

    CNP_MSG = 14;
    
    SOCK_TO_SOCK_DATA_MSG = 15;
    // timers
}

// The basic msg used as DataMsg, ReceivedMsg, SyncMsg, etc.
// So the only difference of these msgs is the kind of the 
// msgs and the size of them.
// Have to set the kind of this msg!
message FlowMsg extends cPacket {
    Flow the_flow;
}

// Used when the cpu tells the gpu to send to multiple dests
message FlowVectorMsg extends cPacket {
    FlowVector the_flows;
}

//message TorusDataMsg extends BasicMsg {
    //int plane=-1; // Assuming that the packet just flow in a certain plane,
    //int route[4];
//}

// This msg can be used between task_gen&controller
message TaskMsg extends cPacket {
    Task now_task;
}

// Used when the centrolontroller tells the cpu to start a task
message TaskFlowVecMsg extends TaskMsg {
    FlowVector the_flows;
    int targetId = -1;
}

// Used when the SDN tells the switches to update its route table
message RouteVecMsg extends cPacket {
    RouteVec new_route_table;
    int targetId = -1;
    int index;  // used to identify the router index
}

message SelfMsg extends cPacket {
    int argument;
}

message WaitMsg extends cPacket {
    simtime_t wait_time;
}

message SimpleMsg extends cPacket {
    int argument;
}
